/* eslint-disable react/prop-types */
/* eslint-disable no-console */
/* eslint-disable no-param-reassign */
/* eslint-disable react/forbid-prop-types */
/**
 * 左侧树右侧diff组件，在详情页和比较页有使用到
 * @param {string} commitId commit ID
 * @param {array} diffs 右侧diffs数据来源
 * @param {func} onChange 用于自定义onChange事件
 * @param {object} curCommitInfo 当前commit信息
 * @param {boolean} showCommentList 是否显示左下角评论区块
 * @param {boolean} isInCommitDetail 是否显示在详情弹窗内，默认false
 * @return {element} 组件
 */
import React from 'react';
import PropTypes from 'prop-types';
import utils from 'utils';
import { Balloon, Button, Badge, Tab } from '@teamix/ui';
import { YunxiaoIcon, ButtonIcon, SideBar } from '@alife/devops-ui';
import { getMoreLines, getWebIdeUrl } from 'api';
import Diff from 'components/diff';
import ListEmpty from 'atComponents/ListEmpty';
import FilePanel from 'components/diffPanel';
import FileName from './fileName/index.jsx';
import diffUtils from 'components/diff/utils.js';
import sha1 from 'sha1';
import LeftTree from './tree';
import './index.scss';
import track from 'utils/track';
import LfsDeleteTag from 'components/lfs/deleteTag';
import LfsTag from 'components/lfs/lfsTag';
import intl from '../../locale';
import UILessPluginForCode from 'components/UILessPluginForCode';
import MoreThanOneOverlay from 'components/commitDetail/tag/moreThanOneOverlay.jsx';
import Tags from 'components/commitDetail/tag/index.jsx';
import Commitcomment from './comment';
import AddAndDeleteTag from './addAndDeleteTag/index';
import exceed from 'utils/apimap';
import { getPathWithRootPath, navigateOpen } from 'utils/router';
import { getFeature } from 'utils/features';

// const { Colorable: ColorTag } = Tag;
// const { Popup } = Overlay;

const { Tooltip } = Balloon;

export default class CommitDetail extends React.Component {
  static propTypes = {
    commitId: PropTypes.string,
    onChange: PropTypes.func,
    diffs: PropTypes.array,
    curCommitInfo: PropTypes.object,
    isInCommitDetail: PropTypes.bool,
    // 为获取图片对比，增加参数
    fromBranch: PropTypes.string,
    genWatermarkimage: PropTypes.object,
  };

  static defaultProps = {
    commitId: '',
    onChange: () => {},
    diffs: [],
    curCommitInfo: {},
    isInCommitDetail: false,
    fromBranch: '',
  };

  constructor(props) {
    super(props);
    this.state = {
      forceDiffViewType: utils.getCachedData('forceDiffViewType') || 'unified',
      // 是否隐藏panel的数组
      hideArray: [],
      hash: {},
      downState: false,
      treeState: true,
      resourcesVisi: false,
      commitTreeHeight: 0,
      // commitChangeFile: 0,
      comitScllTop: false,
      // Watermark: {},
    };
    this.container = null;
    this.imageObserver = null;
    this.btn = null;
    this.commitContainerRef = React.createRef();
    this.rightContentRef = React.createRef();
    this.diffTriggerMap = [
      {
        value: 'unified',
        label: '单栏',
      },
      {
        value: 'watermelon',
        label: '双栏',
      },
    ];
  }

  //  这里可以优化注释的。
  //  当对比或者 提交的问题 大于 9 个的时候， 全部显示改动
  // static getDerivedStateFromProps(props, state) {
  //   if (!state.hideArray) {
  //     const hideArray = props.diffs.map((item, index) => {
  //       return index > 9;
  //     });
  //     return { hideArray };
  //   }
  // }

  componentDidMount() {
    const { isInCommitDetail, isNewCommitOnchange } = this.props;
    if (isInCommitDetail && isNewCommitOnchange) {
      this.getIpWhite();
      this.getCloneDownloadSetting();
      this.commitScrollTop();
      this.newCommitChangecomputeHeight();
    } else if (isInCommitDetail) {
      const rightContent = document.querySelector('.commit-right-content');
      rightContent && rightContent.addEventListener('scroll', this.onScroll);
      this.computeHeight();
    }
    if (this.props.genWatermarkimage) {
      this.backageImageMutationObserver(); // 这个是水印相关的函数
    }
    this.commitAutoScrollToComment();
    // commit列表的评论数量跳转过来，需要到底部的全文评论
    if (utils.getUrlSearchParam('anchor') === 'bottom') {
      setTimeout(() => {
        this.tipsComment(this.commitContainerRef.current);
      }, 120);
    }
  }

  componentWillUnmount() {
    this.imageObserver && this.imageObserver.disconnect();
  }

  backageImageMutationObserver = () => {
    // 选择需要观察变动的节点
    const targetNode = this.container;
    // 观察器的配置（需要观察什么变动）
    const config = { attributes: true, childList: true, subtree: true };
    // 当观察到变动时执行的回调函数
    const callback = (mutationsList) => {
      // Use traditional 'for loops' for IE 11
      for (const mutation of mutationsList) {
        if (mutation.type === 'attributes') {
          targetNode.style.backgroundImage = utils.isGenWatermarkimage(
            this.props.genWatermarkimage,
          );
        }
      }
    };
    // 创建一个观察器实例并传入回调函数
    this.imageObserver = new MutationObserver(callback);
    // 以上述配置开始观察目标节点
    targetNode && this.imageObserver.observe(targetNode, config);
  };

  onScroll = () => {
    // diff panel顶部在视图内，或者底部还在视图内 高亮指定tree-item
    const allPanel = document.querySelectorAll('.commit-right-content .diff-panel-wrapper');
    const distance = this.getDistance();
    // 默认为第一个
    let activeFilePanel = allPanel[0];
    for (let i = 0; i < allPanel.length; i++) {
      const curFilePanel = allPanel[i];
      const rect = curFilePanel.getBoundingClientRect();
      const hasActive = rect.top > distance || rect.bottom > distance;
      if (hasActive) {
        activeFilePanel = curFilePanel;
        break;
      }
    }
    if (!activeFilePanel) {
      return;
    }
    const id = activeFilePanel.getAttribute('id');
    const sha = id ? id.replace('anchor_file_', '') : '';
    document
      .querySelectorAll('.changes-tree-item-file-name.active')
      .forEach((dom) => dom.classList.remove('active'));
    document.getElementById(`tree_${sha}`).classList.add('active');
  };

  getDistance = () => {
    let distance = 0;
    if (this.props.isInCommitDetail) {
      const commitDetailHeader = document.querySelector('.commit-detail-header');
      const commitDetailTitle = document.querySelector('.commit-right-content-title');
      distance =
        (commitDetailHeader ? commitDetailHeader.offsetHeight : 0) +
        (commitDetailTitle ? commitDetailTitle.offsetHeight : 0);
    } else {
      const header = document.querySelector('.tb-navigator-container');
      const fixTab = document.querySelector('.project-fix-tab');
      distance = (header ? header.offsetHeight : 0) + (fixTab ? fixTab.offsetHeight : 0);
    }
    return distance;
  };

  componentDidUpdate(prevProps, prevState) {
    const { isShowAllDes, isNewCommitOnchange } = this.props;
    const { downState } = this.state;
    const { file } = this.state.hash;
    if (
      (prevProps.isShowAllDes !== isShowAllDes || prevState.downState !== downState) &&
      isNewCommitOnchange
    ) {
      this.newCommitChangecomputeHeight();
    } else if (!isNewCommitOnchange) {
      if (file !== prevState.hash.file) {
        const anchor_file = document.querySelector(`#anchor_file_${file}`);
        const distTop = anchor_file.offsetTop - this.getDistance();
        if (anchor_file) {
          // 在详情弹窗内scrollingElement不是滚动元素
          if (this.props.isInCommitDetail) {
            document.querySelector('.commit-right-content').scrollTop = distTop;
          } else {
            document.scrollingElement.scrollTop = distTop;
          }
        }
      } else {
        // 如果滚动后，高亮行变了，但是hash没变，此时点击改行，不会滚动，但是高亮需要恢复
        const treeItemList = document.querySelectorAll('.changes-tree-item-file-name.active');
        treeItemList && treeItemList.forEach((dom) => dom.classList.remove('active'));
        const curTreeItem = document.getElementById(`tree_${file}`);
        if (curTreeItem) {
          curTreeItem.classList.add('active');
        } else {
          // 初始化时默认第一个高亮
          if (!this.props.diffs[0]) {
            return;
          }
          const firstDiffSha = sha1(this.props.diffs[0].new_path);
          const firstTreeItem = document.getElementById(`tree_${firstDiffSha}`);
          firstTreeItem.classList.add('active');
        }
      }
    }
  }

  // 保留
  commitAutoScrollToComment = () => {
    const elementParent = this.rightContentRef.current;
    const elementCommitBtn = this.commitContainerRef.current;
    if (elementParent && elementCommitBtn) {
      // 可滚动长度
      const canScrollLength = elementParent.scrollHeight - elementParent.offsetHeight;
      // 评论内容刚出现时，此时已经滚动的长度
      const topLength = canScrollLength - elementCommitBtn.offsetHeight;
      if (elementParent.scrollTop >= topLength) {
        this.setState({ comitScllTop: true });
      } else {
        this.setState({ comitScllTop: false });
      }
    }
  };

  // 到评论区
  tipsComment = (commentContainer) => {
    const elementParent = this.rightContentRef.current;

    if (commentContainer && elementParent) {
      const elementCommitBtn = this.commitContainerRef.current;
      // 可滚动长度
      const canScrollLength = elementParent.scrollHeight - elementParent.offsetHeight;
      // 评论内容刚出现时，此时已经滚动的长度
      const topLength = canScrollLength - elementCommitBtn.offsetHeight;
      elementParent.scrollTo({
        // 直接到评论底部
        // top: elementParent.scrollHeight - elementParent.offsetHeight,
        // 到"评论"，+符号后面的数值可调
        top: topLength + elementParent.offsetHeight,
      });
    }
  };

  // 监听滚动
  commitScrollTop = () => {
    const elementParent = this.rightContentRef.current;
    if (elementParent) {
      elementParent.onscroll = () => {
        const elementCommitBtn = this.commitContainerRef.current;
        // 可滚动长度
        const canScrollLength = elementParent.scrollHeight - elementParent.offsetHeight;
        // 评论内容刚出现时，此时已经滚动的长度
        const topLength = canScrollLength - elementCommitBtn.offsetHeight;
        if (elementParent.scrollTop >= topLength) {
          this.setState({ comitScllTop: true });
        } else {
          this.setState({ comitScllTop: false });
        }
      };
    }
  };

  // 直接到顶部
  commitTipsScrollTop = () => {
    this.setState({ comitScllTop: false }, () => {
      const elementParent = document.getElementsByClassName('commit-right-content-list')[0];
      elementParent.scrollTop = 0;
    });
  };

  getIpWhite = () => {
    const { organization } = window.FORCE;
    exceed
      .fetch({
        api: 'organization.ip_setting',
        params: {
          id: organization.id,
        },
      })
      .then((result) => {
        this.setState({
          ipSetting: result,
        });
      });
  };

  getCloneDownloadSetting = () => {
    const { pathResource } = window.FORCE;
    exceed
      .fetch({
        api: 'project.clone_download',
        params: {
          projectId: pathResource.id,
        },
      })
      .then((result) => {
        this.setState({
          project_clone_download: result,
        });
      });
  };

  setHash = (file) => {
    this.setState({
      hash: {
        ...this.state.hash,
        file,
      },
    });
  };

  // 计算高度
  computeHeight = () => {
    const treeWrapper = document.querySelector('.left-tree-content');
    if (!treeWrapper) {
      return;
    }
    if (!this.props.showCommentList) {
      treeWrapper.style.borderBottom = '0px';
      return;
    }
    const detailPage = document.querySelector('.commit-detail-page');
    const headerPage = document.querySelector('.commit-detail-header');
    const commentwrapper = document.querySelector('#comment-wrapper');
    const commentHeight = (commentwrapper && commentwrapper.offsetHeight) || 0;
    const detailPageHeight = (detailPage && detailPage.offsetHeight) || 0;
    const headerPageHeight = (headerPage && headerPage.offsetHeight) || 0;
    const padding = 20;
    treeWrapper.style.height = `${detailPageHeight - commentHeight - headerPageHeight - padding}px`;
  };

  // 计算高度
  newCommitChangecomputeHeight = () => {
    const treeTop = document.querySelector('.left-tree-commit-basic-information');
    const treeTitle = document.querySelector('.left-tree-bottom-header');
    const headerPage = document.querySelector('.commit-detail-header');

    const headerHeight = (headerPage && headerPage.offsetHeight) || 0;
    const treeTopHeight = (treeTop && treeTop.offsetHeight) || 0;
    const treeTitleValue = (treeTitle && treeTitle.offsetHeight) || 0;
    // const changeFileHeight = headerHeight + 72;
    const treeHeigthValue = headerHeight + 72 + treeTopHeight + treeTitleValue + 20;
    this.setState({
      commitTreeHeight: treeHeigthValue,
      // commitChangeFile: changeFileHeight,
    });
  };

  // 获取两行之间的文件内容
  loadMoreLines = (data) => {
    const params = { ...data, commitId: this.props.commitId };
    getMoreLines(params)
      .then((result) => {
        const { hunk, diff, from, to, isAddToEnd, isLoadEndFinished } = data;
        const lineData = {
          hunk,
          diff,
          blob: result.content,
          from,
          to,
          isAddToEnd,
          isLoadEndFinished,
        };

        this.handleReceiveLines(lineData);
      })
      .catch((err) => {
        console.error(err);
      });
  };

  handleReceiveLines = (data) => {
    // 在 hunkKey（即 @@ -6,10 +6,9 @@ 这种）后追加新获取的行，并替换成新计算的 hunkKey
    const { blob, hunk, diff, isAddToEnd, isLoadEndFinished } = data;
    const filepath = diff.newPath;
    const diffs = [...this.props.diffs];
    const blobArr = blob.replace(/\n$/, '').split('\n');
    const lineCnt = blobArr.length;
    const newBlob = blobArr.join('\n ');
    const { newLines, newStart, oldLines, oldStart } = hunk;

    diffs.forEach((item) => {
      if (item.new_path === filepath) {
        const lines = item.diff.split('\n');
        const oldHunkKey = lines.find((line) => line.indexOf(hunk.content) === 0);
        if (hunk.content === 'STUB') {
          if (blobArr.length < 20) {
            item.loadEndFinished = true;
            if (newBlob) {
              item.diff = `${item.diff}\n ${newBlob}`;
            }
          } else {
            item.diff = `${item.diff}\n ${newBlob}`;
            item.lastLineNum = item.lastLineNum ? item.lastLineNum + lineCnt : newStart + lineCnt;
            if (isLoadEndFinished) {
              item.loadEndFinished = true;
            }
          }
        } else if (!isAddToEnd) {
          // 向上展开，即在本hunk前面追加
          const newHunkKey = `@@ -${oldStart - lineCnt > 0 ? oldStart - lineCnt : 1},${
            oldLines + lineCnt
          } +${newStart - lineCnt > 0 ? newStart - lineCnt : 1},${newLines + lineCnt} @@`;
          const splitArr = item.diff.split(oldHunkKey);
          item.diff = `${splitArr[0]}${newHunkKey}\n ${newBlob}${splitArr[1]}`;
        } else {
          // 向下展开，即在本hunk的前一个hunk的最后追加
          const splitArr = item.diff.split(oldHunkKey);
          const prevOldHunkKeyIndex =
            diff.hunks.findIndex((item2) => oldHunkKey.indexOf(item2.content) === 0) - 1;
          const prevOldHunk = diff.hunks[prevOldHunkKeyIndex];
          const prevOldHunkKey = prevOldHunk.content;
          const prevSplitArr = splitArr[0].split(prevOldHunkKey);
          const newHunkKey = `@@ -${prevOldHunk.oldStart},${prevOldHunk.oldLines + lineCnt} +${
            prevOldHunk.newStart
          },${prevOldHunk.newLines + lineCnt} @@`;
          item.diff = `${prevSplitArr[0]}${newHunkKey}${prevSplitArr[1]}\n ${newBlob}\n${oldHunkKey}${splitArr[1]}`;
        }
      }
    });
    this.props.onChange(diffs, 'diffs');
  };

  toggleViewType = (viewType) => {
    this.setState({
      forceDiffViewType: viewType,
    });

    utils.setCachedData('forceDiffViewType', viewType);
  };

  // 手动加载大 diff
  manualLoadDiff = (diff) => {
    const diffs = [...this.props.diffs];
    diffs.forEach((item) => {
      if (item.new_path === diff.new_path) {
        item.diff = item.originalDiff;
      }
    });
    this.props.onChange(diffs, 'diffs');
  };

  // 记录隐藏的索引
  handleHidePanel = (e, index) => {
    e.stopPropagation();
    e.preventDefault();
    const hideArray = [...this.state.hideArray];
    hideArray[index] = !hideArray[index];
    this.setState({
      hideArray,
    });
  };

  renderImgJsx = (commitId, path, type) => {
    const { pathResource } = window.FORCE;
    return (
      <div className={`diff-single-img ${type}`}>
        <img
          src={`/${pathResource.fullPath}/raw/${utils.revisionEncodeURI(commitId)}/${path}`}
          style={{ maxWidth: '90%' }}
        />
      </div>
    );
  };

  renderBinary = (diff) => {
    const { fromBranch, commitId, isInCommitDetail, curCommitInfo } = this.props;
    // commit详情中为curCommitInfo.parent_ids[0]，比较页为oldCommitId
    let fromCommitId = fromBranch;
    if (isInCommitDetail && curCommitInfo.parent_ids && curCommitInfo.parent_ids.length) {
      fromCommitId = curCommitInfo.parent_ids[0];
    }
    if (
      diff.is_binary &&
      utils.isImageSuffix(diff.deleted_file ? diff.old_path : diff.new_path) &&
      fromCommitId
    ) {
      // 如果是比较页，则有oldCommitId；如果是详情页则只有图片删除或者增加,直接取comitId
      if (diff.deleted_file) {
        return this.renderImgJsx(fromCommitId, diff.old_path, 'delete');
      }
      if (diff.new_file) {
        return this.renderImgJsx(commitId, diff.new_path, 'new');
      }
      return (
        <div className="diff-img-wraper">
          {this.renderImgJsx(fromCommitId, diff.old_path, 'delete')}
          {this.renderImgJsx(commitId, diff.new_path, 'new')}
        </div>
      );
    }
    const is_lfs = diff.is_old_lfs || diff.is_new_lfs;
    if (is_lfs) {
      return this.renderLfsFile();
    }
    return (
      <div className="binary-placeholder">
        {intl.get({
          id: 'code-assets.components.treeAndDiff.TheFileContentIsToo',
          defaultMessage: '文件内容过大或为二进制文件，暂不支持比较',
        })}
      </div>
    );
  };

  renderLfsFile = () => {
    return (
      <div className="binary-placeholder">
        {intl.get({
          id: 'code-assets.components.treeAndDiff.GitLfsFileComparisonIs',
          defaultMessage: '暂不支持Git LFS文件比较',
        })}
      </div>
    );
  };

  renderDiffContentSumAndDiffviewTrigger = () => {
    return (
      <div className="commit-right-content-num-and-diff">
        {this.renderDiffContentSum()}
        <Tab
          size="small"
          shape="capsule"
          activeKey={this.state.forceDiffViewType}
          style={{ width: 'inherit' }}
        >
          <Tab.Item
            key={'unified'}
            title={intl.get({
              id: 'code-assets.components.treeAndDiff.SingleColumn',
              defaultMessage: '单栏',
            })}
            onClick={() => {
              this.toggleViewType('unified');
            }}
          />

          <Tab.Item
            key={'split'}
            title={intl.get({
              id: 'code-assets.components.treeAndDiff.DoubleColumn',
              defaultMessage: '双栏',
            })}
            onClick={() => {
              this.toggleViewType('split');
            }}
          />
        </Tab>
      </div>
    );
  };

  renderDiffContentSum = () => {
    const { diffs } = this.props;

    const result = diffs.reduce(
      (acc, item) => {
        const diffsCount = diffUtils.getSingleDiffsCount(item);
        if (diffsCount) {
          acc.additions += diffsCount.additions;
          acc.deletions += diffsCount.deletions;
        }
        return acc;
      },
      { additions: 0, deletions: 0 },
    );

    return (
      <div className="commit-right-content-num">
        <div className="commit-right-content-num-left">
          <span>改动文件 </span>
          <span className="commit-right-content-num-dot" />
          <span>{diffs.length}</span>
        </div>
        <div className="commit-right-content-num-right">
          <AddAndDeleteTag additions={result?.additions} deletions={result?.deletions} />
        </div>
      </div>
    );
  };

  renderDiffContent = () => {
    const { forceDiffViewType } = this.state;
    const { diffs, curCommitInfo, commitId: sha, genWatermarkimage } = this.props;
    const diffProps = {
      viewType: forceDiffViewType,
      loadMoreLines: this.loadMoreLines,
      manualLoadDiff: this.manualLoadDiff,
    };
    let activeFile = this.state.hash.file;
    if (!activeFile && diffs[0] && diffs[0].new_path) {
      activeFile = sha1(diffs[0].new_path);
    }
    return diffs.map((item, index) => {
      const commitId =
        item.deleted_file && curCommitInfo.parent_ids
          ? curCommitInfo.parent_ids[0]
          : curCommitInfo.sha || curCommitInfo.id || sha;
      const diffsCount = diffUtils.getSingleDiffsCount(item);

      // 计算是否展开
      const { hideArray } = this.state;
      item.isHidden = hideArray && hideArray[index];

      const is_lfs = item.is_new_lfs || item.is_old_lfs;
      const { pathResource, resourceSubject } = window.FORCE;
      const active = sha1(item.new_path) === activeFile ? 'diff-panel-wrapper-active' : '';
      return (
        <FilePanel
          id={`anchor_file_${sha1(item.new_path)}`}
          className={`${
            utils.isGenWatermarkimage(genWatermarkimage)
              ? 'diff_panel_waterMark_image diff-panel-wrapper'
              : 'diff-panel-wrapper'
          } ${active}`}
        >
          <FilePanel.Header>
            <div className="commit-detail-file-header">
              <div className={`commit-detail-file-header-left ${forceDiffViewType}`}>
                <a className="text-black">
                  <FileName
                    item={item}
                    type="normal"
                    onChange={(e) => {
                      this.handleHidePanel(e, index);
                    }}
                  />
                </a>
                {/* 组概览页面点开commit弹窗时，role无法获取，全部按非管理员显示文案; 比较页面可以准确获取 */}
                {is_lfs && !item.deleted_file && (
                  <LfsTag
                    role={
                      resourceSubject && resourceSubject.subject === 'compare'
                        ? pathResource.role
                        : ''
                    }
                  />
                )}
                {is_lfs && item.deleted_file && <LfsDeleteTag />}
                {diffsCount ? (
                  <AddAndDeleteTag
                    additions={diffsCount?.additions}
                    deletions={diffsCount?.deletions}
                  />
                ) : null}
              </div>
              <div className="commit-detail-file-header-right">
                {getFeature('WebIDE.entrance.commit') && this.renderWebIdeBtn(item)}
                {!item.deleted_file && commitId ? (
                  <ButtonIcon
                    type="secondary"
                    component="a"
                    name="folder-line"
                    color="gray"
                    href={getPathWithRootPath(`/${pathResource.fullPath}/blob/${commitId}/${item.new_path}`)}
                    target="_blank"
                    style={{ marginLeft: 12 }}
                    onClick={() => {
                      if (this.props.isInCommitDetail) {
                        track({
                          action: 'view_commit_source_file',
                          page: 'Modal-Commit',
                          type: '',
                          control: 'file',
                        });
                      }
                    }}
                  />
                ) : null}
              </div>
            </div>
          </FilePanel.Header>
          <FilePanel.Body noPadding>
            <div style={{ display: item.isHidden ? 'none' : 'block' }}>
              {!item.is_binary ? (
                <React.Fragment>
                  {is_lfs ? (
                    this.renderLfsFile()
                  ) : (
                    <Diff {...diffProps} diff={item} genWatermarkimage={genWatermarkimage} />
                  )}
                </React.Fragment>
              ) : (
                this.renderBinary(item)
              )}
            </div>
          </FilePanel.Body>
        </FilePanel>
      );
    });
  };

  getDiffsSha1Map = (diffs) => {
    if (!(diffs && diffs.length)) {
      return {};
    }
    const diffsSha1Map = {};
    diffs.forEach((diff) => {
      diffsSha1Map[sha1(diff.new_path)] = diff.new_path;
    });
    return diffsSha1Map;
  };

  renderDiffNullContent = () => {
    return (
      <ListEmpty
        size="small"
        type="card"
        content="文件过多"
        description={
          <div style={{ display: 'flex', alignItems: 'center' }}>
            提交内容过多，请本地执行 git diff 命令查看
          </div>
        }
        image="none"
        className="no-content no-btns"
      />
    );
  };

  goWebIde = (e, path) => {
    const branch = utils.getUrlSearchParam('branch');
    e.preventDefault();
    getWebIdeUrl({
      filepath: `/${path}`,
      branch,
      commit: this.props.commitId,
      line: '',
      column: '',
      type: 'view',
      merge_commit: '',
      mergerequestId: '',
    })
      .then((result) => {
        navigateOpen(result.endpoint);
      })
      .catch((err) => {
        console.error(err);
      });
  };

  renderWebIdeBtn = (diff) => {
    const fileValue = diff.new_path;
    const { ipSetting, project_clone_download } = this.state;
    if (ipSetting?.ip_whitelist_enabled && ipSetting?.scope === 'all') {
      return (
        <Balloon.Tooltip
          align="l"
          trigger={
            <Button type="normal" size="small" text style={{ marginLeft: 16 }} disabled>
              WebIDE
            </Button>
          }
        >
          {intl.get({
            id: 'code-assets.containers.file.fileItem.TheEnterpriseHasEnabledIp',
            defaultMessage: '企业已启用 IP 白名单严格管控，暂不支持使用 WebIDE',
          })}
        </Balloon.Tooltip>
      );
    } else if (
      project_clone_download?.httpCloneLimit?.state === 'disable' &&
      project_clone_download?.sshCloneLimit?.state === 'disable'
    ) {
      return (
        <Balloon.Tooltip
          align="l"
          trigger={
            <Button type="normal" size="small" text style={{ marginLeft: 16 }} disabled>
              WebIDE
            </Button>
          }
        >
          已启用仓库克隆下载控制，暂不支持使用 WebIDE，请联系管理员处理
        </Balloon.Tooltip>
      );
    }
    return (
      <Button
        type="normal"
        size="small"
        text
        component="a"
        target="_blank"
        onClick={(e) => {
          this.goWebIde(e, fileValue);
        }}
        style={{ marginLeft: 16 }}
      >
        WebIDE
      </Button>
    );
  };

  AssResources = () => {
    this.setState({
      resourcesVisi: !this.state.resourcesVisi,
    });
  };

  commentCountBadgeStyle = (num) => {
    if (num < 10) {
      return '-16px';
    }
    if (num > 9 && num < 100) {
      return '-26px';
    }
    return '-33px';
  };

  onClickCommentScrollButton = () => {
    this.tipsComment(this.commitContainerRef.current);
    // 评论区快捷按钮点击时，埋点
    track({
      action: 'click_comment_icon',
      page: 'Repo-Commit',
      type: '',
      control: '',
    });
  };

  getCommentLengthByFilter = () => {
    return (this.props.commentList || []).filter((item) => !item.parent_id).length;
  };

  commitChangeCommentScrollTopHander = () => {
    const { isNewCommitOnchange } = this.props;
    const { comitScllTop } = this.state;
    if (isNewCommitOnchange && comitScllTop) {
      return (
        <div className="commit-conent-tips-comment" onClick={this.commitTipsScrollTop}>
          <div className="commit-comment-icons">
            <Button text>
              <YunxiaoIcon type="arrow-up-line" />
            </Button>
          </div>
        </div>
      );
    } else if (isNewCommitOnchange && !comitScllTop) {
      const commentLength = this.getCommentLengthByFilter();
      return (
        <div className="commit-conent-tips-comment" onClick={this.onClickCommentScrollButton}>
          <Tooltip
            align="t"
            trigger={
              <div className="commit-comment-icons">
                <YunxiaoIcon type="new-message-line" />
                <Badge
                  count={commentLength > 99 ? '99+' : commentLength}
                  overflowCount={99}
                  style={{
                    position: 'absolute',
                    backgroundColor: '#fff',
                    color: '#8b8b8b',
                    border: '1px solid #e8e8e8',
                    top: -25,
                    right: this.commentCountBadgeStyle(commentLength),
                    boxShadow: 'none',
                  }}
                />
              </div>
            }
          >
            评论
          </Tooltip>
        </div>
      );
    }
  };

  onBasicInfomationClick = () => {
    const { downState } = this.state;
    this.setState({ downState: !downState });
    // 点击基础信息 panel 埋点
    track({
      action: 'check_commit_info',
      page: 'Repo-Commit',
      type: '',
      control: '',
    });
  };

  render() {
    // forceDiffViewType
    const { hash, downState, treeState } = this.state;
    const {
      diffs,
      loading,
      errorInfo,
      computebranches,
      branches,
      genWatermarkimage,
      tags,
      changeTags,
      curCommitInfo,
      isNewCommitOnchange,
    } = this.props;

    const parentsLength = curCommitInfo.parent_ids ? curCommitInfo.parent_ids.length : '';
    const diffsSha1Map = this.getDiffsSha1Map(diffs);
    if (errorInfo) {
      return <ListEmpty content={errorInfo} image="none" />;
    }

    if (!diffs.length) {
      return (
        <ListEmpty
          content={intl.get({
            id: 'code-assets.components.treeAndDiff.NoFileChanges',
            defaultMessage: '没有文件改动',
          })}
          image="none"
        />
      );
    }

    return (
      <>
        {isNewCommitOnchange ? (
          <div
            ref={(el) => {
              this.container = el;
            }}
            className="commit-detail-bottom-commit-change"
            style={{
              backgroundImage: utils.isGenWatermarkimage(genWatermarkimage) || '',
            }}
          >
            <SideBar
              noPadding
              draggable
              onDrag={() => {}}
              size="medium"
              style={{ width: 280, minWidth: 275, maxWidth: '50%', margin: 0 }}
            >
              <div className="commit-left-tree">
                <div className="left-tree-commit-basic-information">
                  <div
                    className="commit-basic-information-header"
                    onClick={this.onBasicInfomationClick}
                  >
                    <span>基础信息</span>
                    <span>
                      <YunxiaoIcon
                        type={downState ? 'arrow-down-2-line' : 'arrow-right-2-line'}
                        style={{ color: '#8B8B8B' }}
                      />
                    </span>
                  </div>
                  {downState && (
                    <div className="commit-basic-information-connet">
                      <div className="commit-basic-information-connet-list">
                        <div className="information-connet-list-title">所属分支</div>
                        <div className="information-connet-list-content">
                          <MoreThanOneOverlay data={computebranches(branches)} itemType="normal" />
                        </div>
                      </div>
                      {tags?.length > 0 && (
                        <div className="commit-basic-information-connet-list">
                          <div className="information-connet-list-title">标签</div>
                          <div className="information-connet-list-content">
                            <Tags
                              tags={this.props.computeTags(tags)}
                              onChange={changeTags}
                              branch={curCommitInfo.id}
                            />
                          </div>
                        </div>
                      )}
                      {parentsLength ? (
                        <div className="commit-basic-information-connet-list">
                          <div className="information-connet-list-title">父提交</div>
                          <div className="information-connet-list-content">
                            <MoreThanOneOverlay
                              data={this.props.computeParentIds(curCommitInfo.parent_ids)}
                            />
                          </div>
                        </div>
                      ) : null}
                      <div
                        className="commit-basic-information-connet-list"
                        ref={(ref) => {
                          this.btn = ref;
                        }}
                      >
                        <UILessPluginForCode
                          identifier="plugin_for_code_commit"
                          container={{
                            target: 'commit',
                            id: this.props.curCommitInfo?.id,
                            newCommit: true,
                          }}
                          associatePanelOptions={this.props.associatePanelOptions}
                        />
                      </div>
                    </div>
                  )}
                </div>
                <div className="left-tree-divider" />
                <div className="left-tree-content">
                  <div className="tree-wrapper">
                    <div className="left-tree-bottom">
                      {treeState && (
                        <LeftTree
                          diffs={diffs}
                          loading={loading}
                          diffsSha1Map={diffsSha1Map}
                          hash={hash}
                          setHash={this.setHash}
                          commitTreeHeight={this.state.commitTreeHeight}
                          isNewCommitOnchange
                        />
                      )}
                    </div>
                  </div>
                </div>
              </div>
            </SideBar>
            <div className="commit-right-content">
              {this.renderDiffContentSumAndDiffviewTrigger()}
              <div ref={this.rightContentRef} className="commit-right-content-list">
                {this.renderDiffContent()}
                <Commitcomment
                  commentList={this.props.commentList}
                  postInfo={this.props.postInfo}
                  curCommitInfo={this.props.curCommitInfo}
                  commitRef={this.commitContainerRef}
                />
              </div>
            </div>
          </div>
        ) : (
          <div
            ref={(el) => {
              this.container = el;
            }}
            className="commit-detail-bottom"
            style={{
              backgroundImage: utils.isGenWatermarkimage(genWatermarkimage) || '',
            }}
          >
            <div className="commit-left-tree commit-left-tree-in-compare">
              <div className="left-tree-content">
                <div className="tree-wrapper">
                  <div className="left-tree-bottom">
                    <LeftTree
                      diffs={diffs}
                      loading={loading}
                      diffsSha1Map={diffsSha1Map}
                      hash={hash}
                      setHash={this.setHash}
                    />
                  </div>
                </div>
              </div>
            </div>
            <div className="commit-right-content">
              {this.renderDiffContentSumAndDiffviewTrigger()}
              {/* {diffs?.length > 200 ? this.renderDiffNullContent() : this.renderDiffContent()} */}
              {this.renderDiffContent()}
            </div>
          </div>
        )}
        <React.Fragment>{this.commitChangeCommentScrollTopHander()}</React.Fragment>
      </>
    );
  }
}
